package org.example.JVM.ASM.UseASM;


import org.example.JVM.ByteCode.Util.ByteCodeUtils;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import java.io.IOException;

import static org.objectweb.asm.Opcodes.*;

/**
 * @description:
 * @author: farprt
 * @create: 2022-11-16 21:50
 **/
public class UseAsmCreateClass {

    public static void main(String[] args) throws IOException {
        String className = "org.example.JVM.ASM.GenerateCode.AsmGenerateClass";
        String signature = "L" + className.replace(".", "/") + ";";
        // 字节计算局部变量表和操作数栈大小、栈映射帧
        ClassWriter classWriter = new ClassWriter(0);

        classWriter.visit(Opcodes.V1_8, ACC_PUBLIC
                , className.replace(".", "/")
                , signature
                , Object.class.getName().replace(".", "/")
                , null);

        MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC
                , "<init>"
                , "()V"
                , null
                , null);
        methodVisitor.visitCode();
        // 调用父类构造器
        methodVisitor.visitVarInsn(ALOAD, 0);
        methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
        // 添加一条返回指令
        methodVisitor.visitInsn(RETURN);
        // 设置操作数栈和局部变量表大小
        methodVisitor.visitMaxs(1, 1);

        FieldVisitor fieldVisitor = classWriter.visitField(ACC_PUBLIC | ACC_STATIC | ACC_FINAL, "age", "I", null, 19);
        FieldVisitor fieldVisitor1 = classWriter.visitField(ACC_PRIVATE, "name", "Ljava/lang/String;", null, null);
        fieldVisitor1.visitAnnotation("Llombok/Getter", false);

        classWriter.visitEnd();
        byte[] byteCode = classWriter.toByteArray();
        ByteCodeUtils.saveToFile(className, byteCode);
    }
}